<template>
  <div>
    <el-card v-if="enable" class="box-card" style="margin-bottom:10px;position:relative;">
      <el-button @click="actionInstall">安装 Mysql</el-button>
    </el-card>

    <el-dialog title="安装 Mysql 数据库" 
      v-if="installation.enable" 
      :visible.sync="installation.enable"
      :close-on-click-modal="false"
    >
      <div class="mb-1">{{installation.message}}</div>
      <div id="mysql-installation-terminal"></div>
      <span slot="footer" class="dialog-footer">
        <el-button v-if="'start' == installation.status" @click="actionMysqlInstallationClose">取消</el-button>
        <el-button v-if="'start' == installation.status" type="primary" @click="actionMysqlInstallationStart">执行</el-button>
        <el-button v-if="'done' == installation.status" type="primary" @click="actionMysqlInstallationClose">关闭</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import Common from '../../utils/Common.js'
import { Terminal } from 'xterm'
require('xterm/css/xterm.css');
import { FitAddon } from "xterm-addon-fit";
import ini from 'ini'
export default {
    name : 'CardMysqlSetup',
    props : ['enable'],
    data() {
        return {
            installation : {
                enable : false,
                terminal : null,
                shellStream : null,
                message : '即将安装 mysql 数据库',
                status : 'start',
            },
        };
    },
    methods : {
        // 安装 mysql
        actionInstall() {
            this.installation.enable = true;
            this.installation.status = 'start';
            this.installation.message = '即将安装 mysql 数据库';
            this.$forceUpdate();
        },

        // 关闭安装弹框
        actionMysqlInstallationClose() {
            this.installation.enable = false;
            if ( null != this.installation.terminal ) {
                this.installation.terminal.dispose();
            }
            this.$forceUpdate();
        },

        // 开始安装
        async actionMysqlInstallationStart() {
            let $this = this;
            this.installation.message = '正在安装 ...';
            this.installation.status = 'exec';
            this.$forceUpdate();

            this.installation.terminal = new Terminal({
                cursorBlink: true,
                cursorStyle: "underline",
                scrollback: 100,
            });
            const fitAddon = new FitAddon();
            this.installation.terminal.loadAddon(fitAddon);
            this.installation.terminal.open(document.getElementById('mysql-installation-terminal'));
            fitAddon.fit();

            let server = this.$store.getters.serverCurrent;

            // 执行 安装操作
            await (function() {
                return new Promise(async ( resolve, reject ) => {
                    let stream = await server.exec4Stream('apt install mysql-server -y');
                    stream.on("data", (data) => {
                        $this.installation.terminal.write(data.toString());
                    });
                    stream.on('exit', function(code, signal) {
                        if ( 0 != code ) {
                            reject('安装失败');
                        } else {
                            resolve();
                        }
                    });
                });
            })();

            // 执行 mysql_secure_installation
            await (function() {
                return new Promise(async ( resolve, reject ) => {
                    let stream = await server.exec4Stream('mysql_secure_installation');
                    stream.on("data", (data) => {
                        data = data.toString();
                        $this.installation.terminal.write(data);
                        console.log(data);
                        if ( -1 != data.indexOf('Press y|Y for Yes, any other key for No: ') ) {
                            Common.msleep(100);
                            stream.write('n\n');
                            return;
                        }
                        if ( -1 != data.indexOf('New password: ') ) {
                            Common.msleep(100);
                            stream.write('root@temp\n');
                            return;
                        }
                        if ( -1 != data.indexOf('Re-enter new password: ') ) {
                            Common.msleep(100);
                            stream.write('root@temp\n');
                            return;
                        }
                        if ( -1 != data.indexOf('Remove anonymous users? (Press y|Y for Yes, any other key for No) : ') ) {
                            Common.msleep(100);
                            stream.write('y\n');
                            return;
                        }
                        if ( -1 != data.indexOf('Disallow root login remotely? (Press y|Y for Yes, any other key for No) : ') ) {
                            Common.msleep(100);
                            stream.write('n\n');
                            return;
                        }
                        if ( -1 != data.indexOf('Remove test database and access to it? (Press y|Y for Yes, any other key for No) : ') ) {
                            Common.msleep(100);
                            stream.write('y\n');
                            return;
                        }
                        if ( -1 != data.indexOf('Reload privilege tables now? (Press y|Y for Yes, any other key for No) : ') ) {
                            Common.msleep(100);
                            stream.write('y\n');
                            return;
                        }
                    });
                    stream.on('exit', function(code, signal) {
                        if ( 0 != code ) {
                            reject('安装失败');
                        } else {
                            resolve();
                        }
                    });
                });
            })();

            // 修改 ROOT 登录
            let userConfigContent = await server.fileGetContent('/etc/mysql/debian.cnf');
            let userConfig = ini.parse(userConfigContent);
            let password = '';

            try {
                password = await this.$prompt('请输入 root 账号密码', '提示', {
                    confirmButtonText: '确定'
                });
                password = password.value;
            } catch {}
            
            let sqls = [
                `ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '${password}';`,
                "UPDATE mysql.user SET host='%' WHERE user='root';",
                "FLUSH PRIVILEGES;"
            ];
            for ( let i=0; i<sqls.length; i++ ) {
                let cmd = `mysql -u${userConfig.client.user} -p${userConfig.client.password} -e "${sqls[i]}"`;
                await server.exec(cmd);
            }

            let dbconfig = {
                host     : server.host,
                user     : 'root',
                password : password,
                database : 'mysql'
            };
            await server.setConfiguration('mysql', dbconfig);

            // 修改配置文件
            let serverConfigContent = await server.fileGetContent('/etc/mysql/mysql.conf.d/mysqld.cnf');
            let serverConfig = ini.parse(serverConfigContent);
            serverConfig['bind-address'] = '0.0.0.0';
            serverConfigContent = ini.stringify(serverConfig);
            await server.filePutContent('/etc/mysql/mysql.conf.d/mysqld.cnf', serverConfigContent);
            
            // 重启服务
            await server.exec('systemctl restart mysql.service');

            this.installation.message = '安装完成';
            this.installation.status = 'done';
            this.$forceUpdate();
            
            this.actionMysqlInstallationClose();
            this.$emit('done');
        },
    }
}
</script>